package com.soilflow.know.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.soilflow.common.core.domain.entity.GamesBetHistory;
import com.soilflow.common.core.domain.entity.GamesBidHistory;
import com.soilflow.common.core.domain.entity.GamesScoreHistory;
import com.soilflow.common.core.domain.entity.GamesUserScore;
import com.soilflow.common.utils.bean.BeanUtils;
import com.soilflow.framework.web.domain.server.Sys;
import com.soilflow.know.mapper.GamesBetHistoryMapper;
import com.soilflow.know.mapper.GamesBidHistoryMapper;
import com.soilflow.know.mapper.GamesUserScoreMapper;
import com.soilflow.know.service.GamesBetHistoryService;
import com.soilflow.know.service.GamesBidHistoryService;
import com.soilflow.know.service.GamesScoreHistoryService;
import com.soilflow.know.service.GamesUserScoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
public class GamesBetHistoryServiceImpl extends ServiceImpl<GamesBetHistoryMapper, GamesBetHistory> implements GamesBetHistoryService {

    @Autowired
    private GamesUserScoreService gamesUserScoreService;

    @Autowired
    private GamesScoreHistoryService gamesScoreHistoryService;

    @Override
    public GamesBetHistory selectGamesBetHistoryById(Long id) {
        GamesBetHistory landInfoVos = this.baseMapper.selectGamesBetHistoryById(id);
        return landInfoVos;
    }


    @Override
    public GamesBetHistory selectGamesBetHistoryByBidNo(String bidNo) {
        return baseMapper.selectGamesBetHistoryByBidNo(bidNo);
    }

    @Override
    public GamesBetHistory selectOneGamesBetHistoryListByUserIdOfBetNo(GamesBetHistory Dto) {
        return baseMapper.selectOneGamesBetHistoryListByUserIdOfBetNo(Dto);
    }


    @Override
    public List<GamesBetHistory> selectGamesBetHistoryList(GamesBetHistory dto) {
        List<GamesBetHistory> landInfoVos = this.baseMapper.selectGamesBetHistoryList(dto);
        return landInfoVos;
    }

    @Override
    public List<GamesBetHistory> selectGamesBetHistoryListByUserIdOfBetNo(GamesBetHistory dto){
        List<GamesBetHistory> landInfoVos = this.baseMapper.selectGamesBetHistoryListByUserIdOfBetNo(dto);
        return landInfoVos;
    }

    @Override
    public List<GamesBetHistory> selectGamesBetHistoryListByBidNo(String dto) {
        List<GamesBetHistory> landInfoVos = this.baseMapper.selectGamesBetHistoryListByBidNo(dto);
        return landInfoVos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BigDecimal insertGamesBetHisotry(GamesBetHistory dto) {

        // 第一步： 查询本期下注记录，若没有下注则新增下注记录
        GamesBetHistory landInfo = new GamesBetHistory();
        BeanUtils.copyProperties(dto,landInfo);
        String[] split = landInfo.getBetData().split("\\+");
        String[] money = new String[split.length];
        for(int i=0; i<split.length; i++){
            // 保留2位小数
            Double doubleValue = landInfo.getBetAmount().divide(new BigDecimal(split.length), BigDecimal.ROUND_CEILING).doubleValue();
            money[i] = String.format("%.1f", doubleValue);
        }
        landInfo.setBetMoney(String.join(",", money));

        System.out.println(dto.getBetNo());
        System.out.println(dto.getBetData());
        System.out.println(dto.getBetAmount());
        System.out.println("99999999999999999999999999999999999999999999999");

        GamesBetHistory gamesBetHistory = this.baseMapper.selectOneGamesBetHistoryListByUserIdOfBetNo(dto);

        System.out.println(gamesBetHistory);
        System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
        if(gamesBetHistory == null){
            this.save(landInfo);
        }else{
            // 合并下注内容  [大，大单] [10, 20]
            /**
             * 第一步：结果组合 [大，大单, 大] [10, 20, 30]
             * 第二步：结果去重 [大，大单] [40, 20]
             */
            BigDecimal newAmount = gamesBetHistory.getBetAmount().add(landInfo.getBetAmount());
            // 格式化新的下注金额
            GamesBetHistory gamesBetHistoryNew = this.formatBetData(landInfo, gamesBetHistory);
            // 重新设置下注总金额
            gamesBetHistoryNew.setBetAmount(newAmount);
            this.updateGamesBetHistory(gamesBetHistoryNew);
        }

        // 第二步：修改用户积分总额
        GamesUserScore gamesUserScore = new GamesUserScore();
        gamesUserScore.setUserId(dto.getUserId());
        gamesUserScore.setScore(dto.getBetAmount());
        gamesUserScoreService.delGamesUserScoreOnly(gamesUserScore);

        GamesUserScore newScore = gamesUserScoreService.selectGamesUserScoreByUserId(dto.getUserId());

        // 第三步：增加一条积分减少明细记录
        GamesScoreHistory gamesScoreHistory = new GamesScoreHistory();
        gamesScoreHistory.setUserId(dto.getUserId());
        gamesScoreHistory.setUserName(newScore.getUserName());
        gamesScoreHistory.setType("3");
        gamesScoreHistory.setScore(dto.getBetAmount());
        gamesScoreHistory.setUserScore(newScore.getScore());
        gamesScoreHistory.setScoreTime(new Date());
        gamesScoreHistory.setOrigin("下注");

        gamesScoreHistoryService.save(gamesScoreHistory);

        return newScore.getScore();
    }

    /**
     * 格式：大+大单+小
     * 格式：100, 200, 300
     * @param betNew
     * @param betOld
     * @return
     */
    public GamesBetHistory formatBetData(GamesBetHistory betNew, GamesBetHistory betOld){

        HashMap<String, String>  res = new HashMap<>();
        final String[] splitDataNew = betNew.getBetData().split("\\+");
        final String[] splitMoneyNew = betNew.getBetMoney().split(",");
        final String[] splitDataOld = betOld.getBetData().split("\\+");
        final String[] splitMoneyOld = betOld.getBetMoney().split(",");

        for(String str : splitDataNew){
            System.err.println(str);
        }
        System.err.println("----------------------------");

        for(String str : splitMoneyNew){
            System.err.println(str);
        }
        System.err.println("----------------------------");

        for(String str : splitMoneyOld){
            System.err.println(str);
        }
        System.err.println("----------------------------");

        for(String str : splitDataNew){
            System.err.println(str);
        }
        System.err.println("----------------------------");

        for(int i=0; i<splitDataOld.length; i++){
            if(splitDataOld[i]!=null && !splitDataOld[i].equals("")){
                res.put(splitDataOld[i], splitMoneyOld[i]);
            }
        }

        for(int i=0; i<splitDataNew.length; i++){
            if(res.get( splitDataNew[i] ) != null){
                // 相同的选项加起来
                BigDecimal bigDecimal1 = new BigDecimal(res.get(splitDataNew[i]));
                BigDecimal bigDecimal2 = new BigDecimal(splitMoneyNew[i]);
                BigDecimal big = bigDecimal1.add(bigDecimal2);
                res.put(splitDataNew[i], String.format("%.1f", big.doubleValue()));
            }else{
                // 新选项直接加入
                res.put(splitDataNew[i], splitMoneyNew[i]);
            }
        }

        String[] keys = new String[res.size()];
        String[] values = new String[res.size()];
        int index = 0;
        for (Map.Entry<String, String> entry : res.entrySet()) {
            keys[index] = entry.getKey();
            values[index] = entry.getValue();
            index++;
        }
        betOld.setBetData(String.join("+", keys));
        betOld.setBetMoney(String.join(",", values));
        return betOld;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BigDecimal cancelGamesBetHisotry(GamesBetHistory dto) {

        // 第一步：查询下注记录
        GamesBetHistory gamesBetHistory = this.baseMapper.selectOneGamesBetHistoryListByUserIdOfBetNo(dto);

        String[] splitData = gamesBetHistory.getBetData().split("\\+");
        String[] splitMoney = gamesBetHistory.getBetMoney().split(",");
        HashMap<String, String> res = new HashMap<>();

        BigDecimal moneyToSub = BigDecimal.ZERO;
        for(int i=0; i<splitData.length; i++){
            if(splitData[i].equals(dto.getBetData())){
                // 删除的选项
                moneyToSub = new BigDecimal(splitMoney[i]);
            }else{
                res.put(splitData[i], splitMoney[i]);
            }
        }

        String[] keys = new String[res.size()];
        String[] values = new String[res.size()];
        int index = 0;
        for (Map.Entry<String, String> entry : res.entrySet()) {
            keys[index] = entry.getKey();
            values[index] = entry.getValue();
            index++;
        }
        gamesBetHistory.setBetData(String.join("+", keys));
        gamesBetHistory.setBetMoney(String.join(",", values));
        gamesBetHistory.setBetAmount(gamesBetHistory.getBetAmount().subtract(moneyToSub));

        // 第二步： 修改下注记录
        this.baseMapper.updateBetDataByBetId(gamesBetHistory);

        // 第三步： 修改用户积分总数,增加积分
        GamesUserScore gamesUserScore = new GamesUserScore();
        gamesUserScore.setUserId(dto.getUserId());
        gamesUserScore.setScore(moneyToSub);
        gamesUserScoreService.addGamesUserScoreOnly(gamesUserScore);

        // 第四步： 返还积分
        GamesUserScore newScore = gamesUserScoreService.selectGamesUserScoreByUserId(dto.getUserId());
        GamesScoreHistory newRecord = new GamesScoreHistory();
        newRecord.setUserId(dto.getUserId());
        newRecord.setUserName(newScore.getUserName());
        newRecord.setType("0");
        newRecord.setScore(moneyToSub);
        newRecord.setUserScore(newScore.getScore());
        newRecord.setScoreTime(new Date());
        newRecord.setOrigin("取消下注加分");
        gamesScoreHistoryService.save(newRecord);

        return newScore.getScore();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGamesBetHistory(GamesBetHistory dto) {
        return this.baseMapper.updateByBetId(dto)>0?true:false;
    }

    @Override
    public Boolean deleteGamesBetHistoryByIds(List<Long> ids) {
        return this.removeByIds(ids);
    }
}
